package middleware

import (
	"bytes"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"guns-go/global"
	"guns-go/model"
	"guns-go/model/request"
	"guns-go/service"
	"io/ioutil"
	"net/http"
)

func OperationLogRecord() gin.HandlerFunc {
	return func(c *gin.Context) {
		var body []byte
		var account string
		if c.Request.Method != http.MethodGet {
			var err error
			body, err = ioutil.ReadAll(c.Request.Body)
			if err != nil {
				global.GVA_LOG.Error("read body from request error:", zap.Any("err", err))
			} else {
				c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
			}
		}
		if claims, ok := c.Get("claims"); ok {
			waitUse := claims.(*request.CustomClaims)
			account = waitUse.Account
		}

		writer := responseBodyWriter{
			ResponseWriter: c.Writer,
			body:           &bytes.Buffer{},
		}
		c.Writer = writer
		c.Next()

		sysOpLog := new(model.SysOpLog)

		sysOpLog.Param = string(body)
		sysOpLog.Result = writer.body.String()
		sysOpLog.Account = account

		if err := service.ExecuteOperationLog(sysOpLog, c); err != nil {
			global.GVA_LOG.Error("create operation log error:", zap.Any("err", err))
		}
	}
}

type responseBodyWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (r responseBodyWriter) Write(b []byte) (int, error) {
	r.body.Write(b)
	return r.ResponseWriter.Write(b)
}
